﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace DataDefinition.Tdx
{
    public class TDX
    {
        XDocument _tdx;
        Dictionary<string, XDocument> _stdxDocuments;
        Dictionary<string, XElement> _flattenFolder;
        Dictionary<string, List<XElement>> _flattenItems;        

        public void Load(string filePath)
        {
            _tdx = XDocument.Load(filePath);

            var folderPath = Path.GetDirectoryName(filePath);
            _stdxDocuments = new Dictionary<string, XDocument>();

            _flattenFolder = null;
            _flattenItems = null;

            foreach (var filename in Directory.GetFiles(folderPath, "*.stdx"))
            {
                if (filename.EndsWith(".bak.stdx", StringComparison.InvariantCultureIgnoreCase))
                    continue;
                var doc = XDocument.Load(filename);

                var file = Path.GetFileName(filename);

                _stdxDocuments.Add(file, doc);
             }
        }

        public Dictionary<string, XElement> GetFlattenFolders(bool reload = false)
        {
            if (_flattenFolder != null && !reload)
            {
                return _flattenFolder;
            }

            _flattenFolder = new Dictionary<string, XElement>();

            var folders = _tdx.Elements("folders");

            BuildFlattenFolderList(folders);

            return _flattenFolder;
        }

        public string GetTitle(XElement item)
        {
            var title = (string)item.Descendants("property")
                 .First(x => (string)x.Attribute("ref") == "title");

            return title;
        }

        public string GetFileName(XElement item)
        {
            var title = (string)item.Descendants("property")
                 .First(x => (string)x.Attribute("ref") == "filename");

            return title;
        }

        public string GetLiveLinkId(XElement item)
        {
            var liveLinkId = (string)item.Descendants("property")
                 .First(x => (string)x.Attribute("ref") == "liveLinkId");

            return liveLinkId;
        }

        public string GetFolderPath(XElement item)
        {
            var folderPath = (string)item.Descendants("property")
                 .First(x => (string)x.Attribute("ref") == "folderPath");

            return folderPath;
        }

        private void BuildFlattenFolderList(IEnumerable<XElement> folders)
        {
            foreach(var folder in folders.Elements("folder"))
            {
                var id = (string)folder.Descendants("property")
                  .First(x => (string)x.Attribute("ref") == "liveLinkId");

                _flattenFolder.Add(id, folder);
                BuildFlattenFolderList(folder.Elements("folders"));
            }
        }

        public Dictionary<string, List<XElement>> GetFlattenItemList(bool reload = false)
        {
            if (_flattenItems != null && !reload)
            {
                return _flattenItems;
            }

            _flattenItems = new Dictionary<string, List<XElement>>();

            foreach (var xdocs in _stdxDocuments.Values)
            {
                var documents = xdocs.Descendants("document");

                foreach (var doc in documents)
                {
                    var id = (string)doc.Descendants("property")
                        .First(x => (string)x.Attribute("ref") == "liveLinkId");

                    if (!_flattenItems.ContainsKey(id))
                    {
                        _flattenItems.Add(id, new List<XElement>());
                    }
                    
                    _flattenItems[id].Add(doc);
                }
            }
            return _flattenItems;
        }
    }
}
